﻿Imports System.Reflection

Public Class PluginManager

    Public Event LoadCompleted As EventHandler(Of EventArgs)
    Protected Sub OnLoadCompleted(ByVal e As EventArgs)
        RaiseEvent LoadCompleted(Me, e)
    End Sub

    Private _Plugins As New List(Of PluginInfo)
    Public ReadOnly Property Plugins As IList(Of PluginInfo)
        Get
            Return _Plugins
        End Get
    End Property

    Public Sub ReloadAsync()
        _Plugins.Clear()
        Dim thread = New Threading.Thread(AddressOf LoadPlugins)
        thread.Start()
    End Sub

    Private Sub LoadPlugins()

        Dim path = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
        If Not System.IO.Directory.Exists(path) Then
            Exit Sub
        End If

        Dim files = System.IO.Directory.GetFiles(path, "*.dll")
        For Each file In files
            Try
                Dim asm = System.Reflection.Assembly.LoadFrom(file)
                For Each t In asm.GetTypes
                    If t.IsClass AndAlso t.IsPublic AndAlso Not t.IsAbstract AndAlso _
                    t.GetInterfaces.Contains(GetType(IPlugin)) AndAlso _
                    t.GetCustomAttributes(GetType(PluginAttribute), True).Count > 0 Then

                        Dim attribute = DirectCast(t.GetCustomAttributes(GetType(PluginAttribute), True).First, PluginAttribute)
                        Dim info = New PluginInfo
                        info.Path = file
                        info.Attribute = attribute

                        If t.GetInterfaces.Contains(GetType(IAlertPlugin)) Then
                            info.Kind = info.Kind Or PluginKinds.Alert
                        End If
                        If t.GetInterfaces.Contains(GetType(IWorkerPlugin)) Then
                            info.Kind = info.Kind Or PluginKinds.Woeker
                        End If
                        If t.GetInterfaces.Contains(GetType(IContextMenuPlugin)) Then
                            info.Kind = info.Kind Or PluginKinds.ContextMenu
                        End If
                        info.ClassName = t.FullName

                        _Plugins.Add(info)

                    End If
                Next

            Catch ex As Exception
#If DEBUG Then
                Stop
#End If
            End Try
        Next


        OnLoadCompleted(EventArgs.Empty)
    End Sub


End Class
